execution/types/accounts, db/state/execctx: extract codeHash without a full account decode - #22468
Merged
Conversation
…a full account decode Split from #22159 (StateCache review findings #22120, finding 7). codeHashForAddr fully decoded every account record it touched — balance parse plus codeHash interning per mem hit — just to read one field. DeserialiseV3CodeHash parses the SerialiseV3 layout only up to and including the codeHash field, is bounds-safe on truncated records (nil on malformed input, unlike the full decoder), returns nil for the empty and zero sentinels to match CodeHash.IsEmpty, and returns a subslice of enc valid only while enc is — every call site consumes it synchronously within the tx.
yperbasis
requested review from
AskAlexSharov,
mh0lt and
sudeepdino008
as code owners
July 14, 2026 11:59
yperbasis
marked this pull request as draft
July 14, 2026 12:12
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes the fast-path code-hash lookup by extracting the codeHash field directly from SerialiseV3-encoded account bytes, avoiding the cost of a full account decode (notably balance parsing and CodeHash interning) when only the hash is needed.
Changes:
- Added
accounts.DeserialiseV3CodeHash(enc []byte) []byteto extract the 32-byte code hash (or returnnilfor malformed/no-code cases) without full decoding. - Updated
SharedDomains.codeHashForAddrto use the new extractor and removed the now-redundantdecodeAccountCodeHash. - Added test coverage validating equivalence vs full
DeserialiseV3and ensuring bounds-safety across truncation/malformed cases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| execution/types/accounts/account.go | Adds a bounds-safe extractor for the codeHash field from SerialiseV3 account encoding. |
| execution/types/accounts/account_test.go | Adds tests for correctness vs full decode and malformed/truncation behavior. |
| db/state/execctx/domain_shared.go | Switches codeHashForAddr to the new extractor and removes the full-decode helper. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
yperbasis
marked this pull request as ready for review
July 14, 2026 14:09
| } | ||
| h := enc[pos : pos+codeHashBytes] | ||
| var zero common.Hash | ||
| if bytes.Equal(h, zero[:]) || bytes.Equal(h, empty.CodeHash[:]) { |
Collaborator
There was a problem hiding this comment.
can: if ch := common.Hash(h); ch == (common.Hash{}) || ch == empty.CodeHash {
Member
Author
There was a problem hiding this comment.
Done in 6c04496 — switched to the direct common.Hash comparison and removed the bytes import. Thanks.
AskAlexSharov
approved these changes
Jul 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split from #22159 (the #22120 StateCache review findings — finding 7's decode-cost half).
What changed
codeHashForAddrfully decoded every account record it touched — balance parse plus codeHash interning per mem hit — just to read one field.accounts.DeserialiseV3CodeHashparses the SerialiseV3 layout only up to and including the codeHash field:CodeHash.IsEmpty,enc, valid only whileencis — all four call sites incodeHashForAddrconsume it synchronously within the tx, and the one retained copy (PutAddrCodeHash) goes through a fixed[32]byte.decodeAccountCodeHashis deleted; its call sites switch to the extractor.Testing
TestDeserialiseV3CodeHashcross-validates the extractor against the fullDeserialiseV3decode over a nonce × balance × codeHash × incarnation matrix.TestDeserialiseV3CodeHashMalformedwalks every truncation point of a record (nil at any cut into the codeHash, the hash beyond it), rejects non-32-byte codeHash fields, and pins the sentinel spellings to nil.Verification:
execution/types/accounts+db/state/execctxsuites, repeated cleanmake lint.Touches
domain_shared.goin hunks disjoint from #22467; the two merge independently.